import { resolve } from 'node:path';
import process from 'node:process';
import fs from 'fs-extra';

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import electron from 'vite-plugin-electron/simple';
import pkg from './package.json';

// 清理产物
'dist-electron release'.split(' ').forEach(fs.removeSync);

export default defineConfig(({ mode }) => {
  const isDev = mode === 'development';
  const minify = false;

  const commonConfig = {
    resolve: {
      alias: {
        '@': resolve('src'),
      },
    },
    define: {
      'import.meta.env.VERSION': JSON.stringify(pkg.version),
    },
  };

  const electronVite = ({ fileName, output }) => ({
    ...commonConfig,
    build: {
      minify,
      lib: fileName ? { fileName } : undefined,
      sourcemap: isDev ? 'inline' : undefined,
      outDir: resolve('dist-electron'),
      rollupOptions: {
        output,
        external: [
          'electron/main',
          ...Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
        ],
      },
    },
  });

  return {
    ...commonConfig,
    // Electron 需要使用相对路径
    base: './',
    build: {
      minify,
      emptyOutDir: true,
      outDir: resolve('dist'),
      rollupOptions: {
        output: {
          manualChunks(id) {
            if (id.includes('node_modules')) {
              return 'vendor';
            }
          },
        },
      },
    },
    plugins: [
      vue(),
      vueJsx(),
      electron({
        main: {
          entry: 'src/electron-main/index.ts',
          vite: electronVite({ fileName: `main` }),
          async onstart({ startup }) {
            await startup(undefined, { stdio: ['inherit', 'inherit', 'pipe', 'ipc'] });
            /**
             * @type {import('child_process').ChildProcessWithoutNullStreams}
             */
            const electronApp = process.electronApp;
            const code32601RE = /"code":-32601/;
            const syntaxErrorRE = /"Uncaught \(in promise\) SyntaxError: Unexpected token 'H'/;

            // 解决终端因为开发工具报错的问题（本质上就是过滤掉不需要的错误信息，未找到报错原因）
            // https://github.com/electron/electron/issues/46903#issuecomment-2866489583
            // https://github.com/electron/electron/issues/41614#issuecomment-2942630728
            electronApp.stderr.on('data', (/** @type {Buffer} */ data) => {
              const message = data.toString();
              if (!code32601RE.test(message) && !syntaxErrorRE.test(message)) {
                console.error(message);
              }
            });
          },
        },
        preload: {
          input: resolve('src/electron-preload/index.ts'),
          vite: electronVite({ output: { entryFileNames: `preload.mjs` } }),
        },
        // Ployfill the Electron and Node.js API for Renderer process.
        // If you want use Node.js in Renderer process, the `nodeIntegration` needs to be enabled in the Main process.
        // See 👉 https://github.com/electron-vite/vite-plugin-electron-renderer
        renderer: process.env.NODE_ENV === 'test'
          // https://github.com/electron-vite/vite-plugin-electron-renderer/issues/78#issuecomment-2053600808
          ? undefined
          : {},
      }),
    ],
    css: {
      preprocessorOptions: {
        scss: {
          charset: false,
        },
      },
      postcss: {
        plugins: [
          {
            postcssPlugin: '_postcss_plugin_local',
            AtRule: {
              charset(atRule) {
                atRule.name === 'charset' && atRule.remove();
              },
            },
          },
        ],
      },
    },
    test: {
      clearMocks: true,
      environment: 'jsdom',
      setupFiles: [resolve('./vitest.setup.ts')],
      reporters: ['default'],
      testTransformMode: {
        web: ['*.{ts,tsx}'],
      },
      coverage: {
        reporter: ['text', 'json-summary', 'json'],
      },
    },
  };
});
